---
title: SAIF.Business.View.Policy security and authorization
summary: Authorization gates, user-type access rules, demo masking, and security dependencies for policy viewing.
status: draft
owner: SAIF Corporation
last_reviewed: 2026-08-21
library: SAIF.Business.View.Policy
reference_type: embedded
---

# SAIF.Business.View.Policy security and authorization

This page documents authorization mechanisms implemented or consumed by this library. Authentication is handled entirely by infrastructure (NTLM/AD) and is not application-level — all code receives a `WindowsIdentity` on the request context.

## Authorization architecture

Authorization is centralized in `clsPolicySecurity`, which applies a two-tier decision for policy access: a coarse Active Directory gate for secure SAIF policies, followed by a user-type-specific authorization matrix that evaluates direct ownership, group membership, auditor assignment, loss-control assignment, or parent-policy fallback. The implementation splits enforcement across Oracle for auditor checks and SQL Server BDS for group, loss-control, and agent policy-list lookups.

```mermaid
flowchart TD
    Caller[Calling code] --> Gate{Secure policy?}
    Gate -- No --> Matrix["Per-user-type authorization<br>matrix"]
    Gate -- Yes --> AD[AD resource check<br>SAIFpolicyInfo]
    AD -- Deny --> Denied[Access denied]
    AD -- Allow --> Matrix
    Matrix --> Oracle[Oracle engine<br>auditor checks]
    Matrix --> BDS[SQL Server BDS engine<br>group, loss-control, agent checks]
    Matrix --> Parent[Parent-policy fallback<br>for policyholders]
    Oracle --> Decision{Authorized?}
    BDS --> Decision
    Parent --> Decision
    Decision -- Yes --> Allowed[Access allowed]
    Decision -- No --> Denied
```

## AD resource catalog

| Resource name | Purpose | Enforcement point | Source |
| --- | --- | --- | --- |
| `SAIFpolicyInfo` | Grants access to policies flagged with the SAIF secure policy code | `clsPolicySecurity.IsPolicyValidForUser` | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |

## Authorization enforcement points

### Programmatic authorization checks

| Class | Method | Resource / Role | Check type | Source |
| --- | --- | --- | --- | --- |
| `clsPolicySecurity` | `IsPolicyValidForUser(ByRef inPolicyData As clsPolicyData)` | Policy visibility decision | `HasAccess` | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `clsPolicySecurity` | `IsPolicyValidForUser(ByRef inPolicyData As clsPolicyData)` | `SAIFpolicyInfo` | `IsAuthorized` | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `clsPolicySecurity` | `IsPolicyValidForUser(ByVal inPolicyNum As Decimal)` | Policy visibility decision | `HasAccess` | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `clsPolicySecurity` | `IsPolicyValidForParentPolicy` | Parent policyholder relationship | `HasAccess` | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `clsPolicySecurity` | `CanSafetyConsultantAccessPolicy` | Loss-control consultant assignment | `HasAccess` | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `clsPolicySecurity` | `CanAuditorAccessPolicy` | Auditor vendor assignment within the 60-day window | `HasAccess` | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `clsPolicySecurity` | `IsInGroup` | Group / chapter membership | `HasAccess` | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `clsPolicySecurity` | `PolicyList` | User-selectable accessible policy set | `HasAccess` | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `clsPolicySecurity` | `ConvertUserTypeToUserAccessLevel` | Demo vs. non-demo access tiering | `HasAccess` | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |

## User-type authorization matrix

| User type | Authorization rule | Related business rules | Source |
| --- | --- | --- | --- |
| SAIF employee | Always allowed after the secure-policy AD gate | [BR-VP-003: Secure policy requires AD authorization](business-rules.md#br-vp-003-secure-policy-requires-ad-authorization), [BR-VP-005: Access granted per user-access-level matrix](business-rules.md#br-vp-005-access-granted-per-user-access-level-matrix) | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| MCO | Always allowed after the secure-policy AD gate | [BR-VP-003: Secure policy requires AD authorization](business-rules.md#br-vp-003-secure-policy-requires-ad-authorization), [BR-VP-005: Access granted per user-access-level matrix](business-rules.md#br-vp-005-access-granted-per-user-access-level-matrix) | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| Medical provider | Always allowed after the secure-policy AD gate | [BR-VP-003: Secure policy requires AD authorization](business-rules.md#br-vp-003-secure-policy-requires-ad-authorization), [BR-VP-005: Access granted per user-access-level matrix](business-rules.md#br-vp-005-access-granted-per-user-access-level-matrix) | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| Bookkeeper | Always allowed after the secure-policy AD gate | [BR-VP-003: Secure policy requires AD authorization](business-rules.md#br-vp-003-secure-policy-requires-ad-authorization), [BR-VP-005: Access granted per user-access-level matrix](business-rules.md#br-vp-005-access-granted-per-user-access-level-matrix) | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| Agent / DemoAgent | User number must match `AgentNum` or `AgencySeqNum` on the policy | [BR-VP-005: Access granted per user-access-level matrix](business-rules.md#br-vp-005-access-granted-per-user-access-level-matrix) | `SAIF.Business.View.Policy/clsPolicySecurity.vb`, `SAIF.Business.View.Policy/clsPolicyData.vb`, `SAIF.Business.View.Policy/clsAgency.vb` |
| Policyholder / DemoPolicyholder | Direct policy match or parent-policy fallback association is required | [BR-VP-004: Invalid or zero policy number is never valid](business-rules.md#br-vp-004-invalid-or-zero-policy-number-is-never-valid), [BR-VP-005: Access granted per user-access-level matrix](business-rules.md#br-vp-005-access-granted-per-user-access-level-matrix), [BR-VP-009: Fallback to parent-policy authorization](business-rules.md#br-vp-009-fallback-to-parent-policy-authorization) | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| Group / DemoGroup | Group/chapter lookup in BDS must confirm policy membership | [BR-VP-005: Access granted per user-access-level matrix](business-rules.md#br-vp-005-access-granted-per-user-access-level-matrix) | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| Loss control / DemoLossControl | Team-assignment user name prefix must match, with `UserIdName` used for demo users | [BR-VP-005: Access granted per user-access-level matrix](business-rules.md#br-vp-005-access-granted-per-user-access-level-matrix), [BR-VP-007: Loss control prefix match](business-rules.md#br-vp-007-loss-control-prefix-match), [BR-VP-008: Demo loss control matched on UserIdName](business-rules.md#br-vp-008-demo-loss-control-matched-on-useridname) | `SAIF.Business.View.Policy/clsPolicySecurity.vb`, `SAIF.Business.View.Policy/clsTeamAssignment.vb` |
| Auditor / DemoAuditor | Auditor vendor must be attached to an eligible audit within the 60-day window | [BR-VP-005: Access granted per user-access-level matrix](business-rules.md#br-vp-005-access-granted-per-user-access-level-matrix), [BR-VP-006: Auditor 60-day access window](business-rules.md#br-vp-006-auditor-60-day-access-window) | `SAIF.Business.View.Policy/clsPolicySecurity.vb`, `SAIF.Business.View.Policy/clsPolicyData.vb` |
| Quick-file user | No branch grants access, so access is denied | [BR-VP-005: Access granted per user-access-level matrix](business-rules.md#br-vp-005-access-granted-per-user-access-level-matrix) | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |

## Access-level ordinals

| Access level | Ordinal | Purpose | Source |
| --- | --- | --- | --- |
| `SAIFEmployee` | 1000 | Highest internal policy-view tier | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `Auditor` | 900 | Standard auditor tier | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `DemoAuditor` | 850 | Demo auditor tier for masked views | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `Losscontrol` | 800 | Standard loss-control tier | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `DemoLossControl` | 750 | Demo loss-control tier for masked views | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `Agent` | 700 | Standard agent tier | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `DemoAgent` | 650 | Demo agent tier for masked views | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `Group` | 600 | Standard group tier | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `DemoGroup` | 550 | Demo group tier for masked views | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `Policyholder` | 500 | Standard policyholder tier | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `DemoPolicyholder` | 450 | Demo policyholder tier for masked views | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `QuickFileUser` | 300 | Lowest tier; used to detect reduced access behavior | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |

## Data-level authorization

| Entity type | Validation method | Mechanism | Source |
| --- | --- | --- | --- |
| Policy | `clsPolicySecurity.IsPolicyValidForUser` | Secure-policy AD gate plus user-type matrix | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| Policyholder parent relationship | `clsPolicySecurity.IsPolicyValidForParentPolicy` | Parent-policy association fallback for policyholders | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| Loss-control assignment | `clsPolicySecurity.CanSafetyConsultantAccessPolicy` | Prefix comparison against team assignment identity | `SAIF.Business.View.Policy/clsPolicySecurity.vb`, `SAIF.Business.View.Policy/clsTeamAssignment.vb` |
| Auditor assignment | `clsPolicySecurity.CanAuditorAccessPolicy` | Oracle count query across `PA_AUDIT`, `PA_AUDITOR`, and `PA_POLICY_PERIOD` | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| Demo data masking | `clsPolicyData.IsDemoUser`, object-level `MaskData` properties | Presentation-side masking with `clsConstants.DataMaskingConstants` | `SAIF.Business.View.Policy/clsPolicyData.vb`, `SAIF.Business.View.Policy/clsPolicyAddress.vb`, `SAIF.Business.View.Policy/clsAgency.vb`, `SAIF.Business.View.Policy/clsTeamAssignment.vb` |

Demo users see masked policy, address, agency, and team-assignment data per [BR-VP-010: Demo users see masked data](business-rules.md#br-vp-010-demo-users-see-masked-data). The masking occurs after data retrieval, so raw values still travel from the database into process memory before the library rewrites presentation-facing fields.

## Segregation of duties

No segregation-of-duties rules were found. This is consistent with the library's read-only design and [BR-VP-027: Create/Insert/Update/Delete SQL are invalid](business-rules.md#br-vp-027-createinsertupdatedelete-sql-are-invalid).

## Security interfaces and contracts

| Interface / Class | Role | Consumers | Source |
| --- | --- | --- | --- |
| `clsPolicySecurity` | Central authorization service for policy-scoped access decisions and accessible policy lists | Calling business/view code* | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `IPolicySecurityDataProvider` | Unimplemented abstraction for supplying policy-security fields independently of `clsPolicyData`* | No implementers found in this repository* | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `clsSecurityPrincipal` | Ambient identity and authorization dependency supplying user type, user number, user name, group chapter, and AD checks | `clsPolicySecurity` | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |
| `clsUserType` | Maps security-principal context into application user categories and demo flags | `clsPolicySecurity` | `SAIF.Business.View.Policy/clsPolicySecurity.vb` |

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Configuration](configuration.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Database tables](database-tables.md)
- [SQL catalog](sql/index.md)
- [Procedures](procedures/index.md)
- [API reference](api/index.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts.

## Sources
- `SAIF.Business.View.Policy/clsAgency.vb`
- `SAIF.Business.View.Policy/clsPolicyAddress.vb`
- `SAIF.Business.View.Policy/clsPolicyData.vb`
- `SAIF.Business.View.Policy/clsPolicySecurity.vb`
- `SAIF.Business.View.Policy/clsTeamAssignment.vb`
